home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 264_01 / strings.c < prev    next >
Text File  |  1980-01-01  |  4KB  |  151 lines

  1. /*
  2.  * strings - find printable strings in binary files
  3.  *
  4.  * A string is any sequence of 4 or more printable characters ending
  5.  * with a newline, dollar sign, or null.  Exit status is the number of
  6.  * files that couldn't be opened.
  7.  *
  8.  * Usage: strings [-o$0] [-number] file...
  9.  *
  10.  * Flags:
  11.  * -o       precede each string by its octal offset in the file.
  12.  * -$       don't allow '$' as a string terminator.
  13.  * -0       any string of 4 (number) or more printable characters is a string.
  14.  * -number  use number as minimum string length instead of 4.
  15.  *
  16.  * This program is in the public domain.
  17.  * David MacKenzie
  18.  * 6522 Elgin Lane
  19.  * Bethesda, MD 20817
  20.  *
  21.  * Latest revision: 04/23/88
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <ctype.h>
  26.  
  27. #define LEN_INITIAL 300        /* Initial space allocated for string. */
  28. #define LEN_INCREMENT 100    /* Amount to increase buffer by on overflow. */
  29.  
  30. /* Command line arguments. */
  31. int     minlen = 4;        /* Minimum length to be considered a string. */
  32. int     show_offset = 0;    /* Display octal offset of string? */
  33. int     dollar_term = 1;    /* '$' can terminate string? */
  34. int     any_term = 0;        /* Any nonprint char can terminate string? */
  35.  
  36. char   *savebuf;        /* Save consecutive ASCII chars. */
  37. int     buflen = LEN_INITIAL;    /* Current max. length of savebuf. */
  38.  
  39. _main(argc, argv)
  40.     int     argc;
  41.     char  **argv;
  42. {
  43.     void    usage();
  44.     char   *malloc();
  45.     int     optind;        /* Loop index. */
  46.     int     errs = 0;        /* Exit status. */
  47.  
  48.     if (!(savebuf = malloc((unsigned) buflen))) {
  49.     perror("malloc");
  50.     exit(1);
  51.     }
  52.  
  53.     for (optind = 1; optind < argc && *argv[optind] == '-'; ++optind)
  54.     while (*++argv[optind])
  55.         switch (*argv[optind]) {
  56.         case 'o':
  57.         show_offset = 1;
  58.         break;
  59.         case '$':
  60.         dollar_term = 0;
  61.         break;
  62.         case '0':
  63.         any_term = 1;
  64.         break;
  65.         default:
  66.         if ((minlen = atoi(argv[optind])) <= 0)
  67.             usage();
  68.         /* Break out of while loop. */
  69.         argv[optind] += strlen(argv[optind]) - 1;
  70.         break;
  71.         }
  72.  
  73.     if (optind == argc)
  74.     usage();
  75.  
  76.     for (; optind < argc; ++optind)
  77.     errs += strings(argv[optind]);
  78.  
  79.     exit(errs);
  80. }
  81.  
  82. int     consecutives;        /* # consecutive printable characters. */
  83.  
  84. /*
  85.  * Display the strings in file.  Return 0 if ok, 1 if error.
  86.  */
  87.  
  88. strings(file)
  89.     char   *file;
  90. {
  91.     long    ftell();
  92.     FILE   *fp;            /* Input file pointer. */
  93.     long    offset = 0L;    /* Location in file for -o flag. */
  94.     int     c;            /* One character of input. */
  95.  
  96.     if (!(fp = fopen(file, "r"))) {
  97.     perror(file);
  98.     return 1;
  99.     }
  100.     consecutives = 0;
  101.     do {
  102.     c = getc(fp);
  103.     if (c == 0 || c == '\n' || dollar_term && c == '$')
  104.         flushbuf(offset);
  105.     else if (isascii(c) && isprint(c)) {
  106.         if (consecutives == 0)
  107.         offset = ftell(fp) - 1L;    /* Loc. of start of string. */
  108.         buffer(c);
  109.     } else if (any_term)
  110.         flushbuf(offset);
  111.     else
  112.         consecutives = 0;
  113.     } while (c != EOF);
  114.  
  115.     (void) fclose(fp);
  116.     return 0;
  117. }
  118.  
  119. buffer(c)
  120.     int     c;
  121. {
  122.     char   *realloc();
  123.  
  124.     savebuf[consecutives] = c;
  125.     if (++consecutives == buflen) {
  126.     buflen += LEN_INCREMENT;
  127.     if (!(savebuf = realloc(savebuf, (unsigned) buflen))) {
  128.         perror("realloc");
  129.         exit(1);
  130.     }
  131.     }
  132. }
  133.  
  134. flushbuf(offset)
  135.     long    offset;
  136. {
  137.     if (consecutives >= minlen) {
  138.     if (show_offset)
  139.         printf("%7lo ", offset);
  140.     printf("%.*s\n", consecutives, savebuf);
  141.     }
  142.     consecutives = 0;
  143. }
  144.  
  145. void
  146. usage()
  147. {
  148.     fprintf(stderr, "Usage: strings [-o$0] [-number] file...\n");
  149.     exit(1);
  150. }
  151.